package com.campusexpresspickup.controller;

import com.campusexpresspickup.entity.UserMenu;
import com.campusexpresspickup.exception.Asserts;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.campusexpresspickup.common.RestResponse;
import com.campusexpresspickup.dto.UpdateUserPasswordParam;
import com.campusexpresspickup.dto.UserLoginParam;
import com.campusexpresspickup.dto.UserParam;
import com.campusexpresspickup.dto.UserUpdateParam;
import com.campusexpresspickup.entity.OauthRole;
import com.campusexpresspickup.entity.OauthUser;
import com.campusexpresspickup.page.OauthUserPage;
import com.campusexpresspickup.service.IOauthRoleService;
import com.campusexpresspickup.service.IOauthUserRoleService;
import com.campusexpresspickup.service.IOauthUserService;
import com.campusexpresspickup.vo.UserInfoVo;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 登录模块
 */
@RestController
@RequestMapping(value = "/oauth-user", name = "登录")
public class OauthUserController {

  @Value("${jwt.tokenHeader}")
  private String tokenHeader;
  @Value("${jwt.tokenHead}")
  private String tokenHead;

  private final IOauthUserService oauthUserService;
  private final IOauthRoleService oauthRoleService;
  private final IOauthUserRoleService oauthUserRoleService;

  public OauthUserController(IOauthUserService oauthUserService,
      IOauthRoleService oauthRoleService,
      IOauthUserRoleService oauthUserRoleService) {
    this.oauthUserService = oauthUserService;
    this.oauthRoleService = oauthRoleService;
    this.oauthUserRoleService = oauthUserRoleService;
  }

  @PostMapping(value = "/login", name = "登录")
  public Object login(@RequestBody UserLoginParam userLoginParam) {
    if (!StringUtils.hasText(StringUtils.trimAllWhitespace(userLoginParam.getAccount()))) {
      Asserts.error("请填写正确的账号");
    }
    if (!StringUtils.hasText(StringUtils.trimAllWhitespace(userLoginParam.getPassword()))) {
      Asserts.error("请填写正确的密码");
    }
    String token = oauthUserService
        .login(userLoginParam.getAccount(), userLoginParam.getPassword());
    if (token == null) {
      return RestResponse.error("账号或密码错误");
    }
    OauthUser oauthUser = oauthUserService.getUserByUsername(userLoginParam.getAccount());
    Map<String, String> map = new HashMap<>();
    map.put("userID", String.valueOf(oauthUser.getId()));
    map.put("userType", String.valueOf(oauthUser.getUserType()));
    map.put("token", token);
    map.put("tokenHead", tokenHead);
    return RestResponse.ok(map, "登录成功");
  }

  @Transactional
  @PostMapping(value = "/register", name = "注册")
  public Object userRegister(@RequestBody UserParam userParam) {
    if (!StringUtils.hasText(userParam.getAccount())) {
      Asserts.error("账号不能为空");
    }
    if (!StringUtils.hasText(userParam.getPassword())) {
      Asserts.error("密码不能为空");
    }
    OauthUser register = oauthUserService.register(userParam);
    if (register == null) {
      RestResponse.error("请填写正确的信息");
    }
    return RestResponse.ok("注册成功");
  }

  @GetMapping(value = "/refreshToken", name = "刷新token")
  public Object refreshToken(HttpServletRequest request) {
    String token = request.getHeader(tokenHeader);
    String refreshToken = oauthUserService.refreshToken(token);
    if (refreshToken == null) {
      return RestResponse.error("token已过期");
    }
    Map<String, String> map = new HashMap<>();
    map.put("token", refreshToken);
    map.put("tokenHead", tokenHead);
    return RestResponse.ok(map, "刷新成功");
  }

  @GetMapping(value = "/getUserInfo", name = "获取当前用户信息")
  public Object getUserInfo(@NotBlank String account) {
    OauthUser oauthUser = oauthUserService.getUserByUsername(account);
    List<UserMenu> menuList = oauthRoleService.getMenuList(oauthUser.getId());
    List<OauthRole> oauthRoleList = oauthUserRoleService.getRoleListByUserId(oauthUser.getId());
    return RestResponse.ok(new UserInfoVo(oauthUser, menuList, oauthRoleList), "查询成功");
  }

  @GetMapping(value = "/logout", name = "登出")
  public Object logOut() {
    return RestResponse.ok("登出成功");
  }

  @PostMapping(value = "/list", name = "列表")
  public Object getUserList(@RequestBody OauthUserPage oauthUserPage) {
    PageHelper.startPage(oauthUserPage.getPageStart(), oauthUserPage.getPageSize());
    List<OauthUser> list = oauthUserService.list(oauthUserPage);
    return RestResponse.ok(new PageInfo<>(list), "查询成功");
  }

  @GetMapping(value = "/{id}", name = "获取用户详情")
  public Object getUserInfoById(@PathVariable Integer id) {
    OauthUser user = oauthUserService.getItem(id);
    if (user != null) {
      return RestResponse.ok(user, "查询成功");
    }
    return RestResponse.error("查询失败");
  }

  @Transactional
  @PostMapping(value = "/update/{id}", name = "修改用户信息")
  public Object updateUserInfoById(@PathVariable Integer id,
      @RequestBody UserUpdateParam userUpdateParam) {
    OauthUser oauthUser = new OauthUser();
    oauthUser.setUserName(userUpdateParam.getUserName());
    oauthUser.setPhone(userUpdateParam.getPhone());
    oauthUser.setUserType(userUpdateParam.getUserType());
    oauthUser.setStatus(userUpdateParam.getStatus());
    oauthUser.setUpdateTime(new Date());
    oauthUser.setPassword(userUpdateParam.getPassword());
    int updateCount = oauthUserService.update(id, oauthUser);
    if (updateCount > 0) {
      return RestResponse.ok("更新成功");
    }
    return RestResponse.error("更新失败");
  }

  @Transactional
  @PostMapping(value = "/updatePassword", name = "更新密码")
  public Object updatePasswordByAccount(
      @RequestBody UpdateUserPasswordParam updateUserPasswordParam) {
    int updatePasswordCount = oauthUserService.updatePassword(updateUserPasswordParam);
    if (updatePasswordCount > 0) {
      return RestResponse.ok(updatePasswordCount, "更新密码成功");
    } else if (updatePasswordCount == -1) {
      return RestResponse.error("提交参数不合法");
    } else if (updatePasswordCount == -2) {
      return RestResponse.error("找不到该用户");
    } else if (updatePasswordCount == -3) {
      return RestResponse.error("旧密码错误");
    } else {
      return RestResponse.error("更新密码失败");
    }
  }

  @PostMapping(value = "/delete/{id}", name = "删除用户")
  public Object deleteUserById(@PathVariable Integer id) {
    int delete = oauthUserService.delete(id);
    if (delete > 0) {
      return RestResponse.ok("删除成功");
    }
    return RestResponse.error("删除失败");
  }

  @Transactional
  @PostMapping(value = "/updateAccountStatus/{id}", name = "修改用户状态")
  public Object updateAccountStatusById(@PathVariable Integer id,
      @RequestParam("status") boolean status) {
    OauthUser oauthUser = new OauthUser();
    oauthUser.setStatus(status);
    int updateCount = oauthUserService.update(id, oauthUser);
    if (updateCount > 0) {
      return RestResponse.ok("更新成功");
    }
    return RestResponse.error("更新失败");
  }

  @PostMapping(value = "/role/update", name = "给用户分配角色")
  public Object updateUserRole(@RequestParam("userId") Integer userId,
      @RequestParam("roleIds") List<Integer> roleIds) {
    int roleCount = oauthUserService.updateRole(userId, roleIds);
    if (roleCount > 0) {
      return RestResponse.ok("分配成功");
    }
    return RestResponse.error("分配失败");
  }

  @GetMapping(value = "/role/{userId}", name = "获取指定用户角色")
  public Object getUserRole(@PathVariable Integer userId) {
    List<OauthRole> roleList = oauthUserService.getRoleList(userId);
    return RestResponse.ok(roleList, "查询成功");
  }

}
